#pragma once
#include "Block.h"
#include "Biome.h"

struct Identifiers
{
	int MinX;
	int MaxX;
	int MinY;
	int MaxY;
	bool Within(XY Pos){
		if(	Pos.X <= MaxX
			&& Pos.X >= MinX
			&& Pos.Y <= MaxY
			&& Pos.Y >= MinY)
			return true;
		return false;
	}
	bool operator=(Identifiers rhs){
		MinX = rhs.MinX;
		MinY = rhs.MinY;
		MaxX = rhs.MaxX;
		MaxY = rhs.MaxY;
	}
	bool operator==(Identifiers rhs){
		if(	MinX == rhs.MinX
			&& MinY == rhs.MinY
			&& MaxX == rhs.MaxX
			&& MaxY == rhs.MaxY)
			return true;
		return false;
	}
	bool operator!=(Identifiers rhs){
		if(	MinX == rhs.MinX
			&& MinY == rhs.MinY
			&& MaxX == rhs.MaxX
			&& MaxY == rhs.MaxY)
			return false;
		return true;
	}
};

class BlockGrid
{
private:
	char * FileName;
	XY ChunkPos;
	Block ** Grid;
	BlockGrid *N,*S,*W,*E;
	bool Active;
	Identifiers Boundaries;
public:
	BlockGrid()
	{
		ChunkPos = XY(0,0);
		Grid = new Block*[GRID_SIZE];
		for(int i = 0;i < GRID_SIZE;++i)Grid[i] = new Block[GRID_SIZE];
		N = S = W = E = NULL;
	}
	BlockGrid(BlockGrid * G)
	{
		//Plus one because of null terminator
		strcpy_s(FileName,strlen(G->FileName)+1,G->FileName);
		ChunkPos = G->ChunkPos;
		for(int y = 0;y < GRID_SIZE;y++)
			for(int x = 0;x < GRID_SIZE;x++)
				Grid[y][x] = G->Grid[y][x];
		N = G->N;S = G->S;E = G->E;W = G->W;
		Active = G->Active;
		Boundaries = G->Boundaries;
	}
	BlockGrid(XY Pos,BlockGrid * N,BlockGrid * E,BlockGrid * S,BlockGrid * W)
	{
		ChunkPos = Pos;
		Grid = new Block*[GRID_SIZE];
		for(int i = 0;i < GRID_SIZE;++i)Grid[i] = new Block[GRID_SIZE];
		this->N = N;
		this->E = E;
		this->S = S;
		this->W = W;
	}
	~BlockGrid()
	{
		for(int i = 0;i < GRID_SIZE;++i)
			delete [] Grid[i];
		delete [] Grid;
		_DELETE(N);_DELETE(S);_DELETE(E);_DELETE(W);
	}
	
	void Initialize(XY Pos,char * MapName);

	bool Linked() {
		if( N && S && W && E )
			return true;
		else return false;
	}

	//if a_R = true return if Active
	// else set activity level
	bool FuncActivity(bool A,bool a_R){
		if(a_R)
			return Active;
		else Active = A;
	}


	Identifiers GetBoundaries() {
		return Boundaries;
	}
	bool WithinBoundaries(XY Pos) {
		return Boundaries.Within(Pos);
	}

	bool CheckNearby(XY Pos)
	{
		if( Pos.X <= ChunkPos.X + 1 && Pos.X >= ChunkPos.X - 1 &&
			Pos.Y <= ChunkPos.Y + 1 && Pos.Y >= ChunkPos.Y - 1)
		{ return true; }
		return false;
	}

	bool SetNearbyGrid(BlockGrid * G) {
		XY Pos = G->GetGridPos();
		if( Pos.X == ChunkPos.X || Pos.Y == ChunkPos.Y ) {
			if( Pos.X == ChunkPos.X - 1 )		{ W = G; return true; }
			else if( Pos.X == ChunkPos.X + 1 )	{ E = G; return true; }
			else if ( Pos.Y == ChunkPos.Y - 1 )	{ S = G; return true; }
			else if( Pos.Y == ChunkPos.Y + 1 )	{ N = G; return true; }
		}
		return false;
	}

	XY GetGridPos() { return ChunkPos; }
	void SetStorageArea(char * C){FileName = C;}
	void Store();
	void FillGrid();
	void SaveToFile();
	void ClearGrid();

	Block GetBlock(int x,int y){return Grid[y][x];}
	void MakeBlocks(int Tag,int number,XY * CursorPos);
	void Update(XY PlayerPos);
	void AddToDrawList();
	Block ** ReturnGrid();
};